I'd like to test how my app behaves when the user signs out of iCloud and my app is in memory. In the iOS Simulator, the "Sign Out" button for iCloud is grayed out so I can't use the simulator to test. I'm hesitant to use a real device tied to my Apple ID because signing out of iCloud System wide has side effects with many apps and I don't want to potentially lose any data.
However, I did test on a real device by going the Settings app -> iCloud and disabled iCloud only for my app. When I do this, the system terminates my app and does not post a CKAccountChangedNotification.
I only tested turning off the iCloud switch for my app. Does the system simply terminate apps when the user logs out of iCloud system wide too? In what cases is the CKAccountChangedNotification posted? Detecting sign out by listening for CKAccountChangedNotification would seem to be pointless if apps are terminated when the user signs out of iCloud.
Post
Replies
Boosts
Views
Activity
I'm working on an app that uses Auto renewable subscriptions. The app uses StoreKit (not StoreKit2). It is pre-release.
I was under the assumption that if the user subscribes via in app purchase on Device 1, and then installs the same app on Device 2 (logged in with the same Apple ID) that the receipt on Device 2 would include the in app purchase receipt on initial install, and therefore by inspecting the receipt locally I could determine that showing onboarding UI on Device 2 is not necessary (and all this could be done locally). Is this not true? I just watched the WWDC 2022 session 110404 "Implement proactive in-app purchase restore" which seems to indicate that this is not the case?
I'm getting ready to release a new app that uses CloudKit. I just deployed my Development schema to Production in CloudKit dashboard.
Is there a way to run my app from Xcode using the CloudKit Production environment for testing? Details of how to test in the production environment are described here: https://developer.apple.com/library/archive/documentation/DataManagement/Conceptual/CloudKitQuickStart/TestingYourApp/TestingYourApp.html
But would be faster (and easier for debugging potential issues) if I could select tell Xcode to use the production environment when running from the debugger. Is this supported?
Thanks
I notice if I pop a view controller off a UINavigationController's navigation stack using the interactivePopGestureRecognizer, every so often the view controller being popped off is not being released from memory.
Haven't been able to come up with a workaround or determine anything that seems to make the issue reproduce reliably. I simply log out dealloc in the view controller that is going to be popped. Push and pop a few times and notice that dealloc doesn't log out after it is being popped off.
Not sure if something in the UI (other animation) that is interrupting the pop gesture's _UINavigationInteractiveTransition ...
I haven't been able to track down what is retaining my view controller. When the issue happens I can see it is still in memory (I have it listen to UISceneWillEnterForegroundNotification and I put the scene in the background then move it to the foreground and hit a breakpoint).
But...I can't seem to figure out what is strongly retaining the view controller. From he debugger I start setting view controller properties to nil to see if I can break a potential retain cycle I created) but no luck. I'm only able to reproduce the memory leak when I dismiss the view controller with the interactive pop gesture (not the back button). I know that's not a lot to go on but am wondering if someone has experience anything similar and has a potential workaround?
I'm currently using a StoreKit configuration file to test auto renewable subscriptions. On my device I am subscribed to subscription with a duration set to weekly. The subscription renewal rate is set to "Monthly Renewal Every 15 Minutes."
This all works fine for awhile. The subscription auto renews. But after a few hours suddenly my app detects that the subscription has expired and the app UI behaves accordingly.
My app does the following:
Looks at the in app purchase receipts and finds the one with the latest expiration date.
If the current date is later than the expiration date of this receipt my app acts like the subscription has expired. I even add a bit of extra time on the expiration date in case an auto renewable transaction gets held up (in the debug environment I add a couple hours).
I don't take any interaction to cancel the subscription in the "Manage StoreKit Transactions" area of Xcode, nor do I do anything programmatically to cancel the subscription. Autorenew just stops working.
I noticed this happens when the in app purchase receipt count is high (currently it is at 1776 in app purchase receipts). So I'm wondering if this is a bug in the StoreKit configuration environment that happens when auto renewing subscriptions causes the in app purchase receipts to grow large and it just quits auto renewing the subscription?
If I navigate to the area in my user interface and resubscribe to the weekly plan it works again for awhile. The issue then will reoccur after a few hours again, forcing me to "resubscribe" to the plan I've never unsubscribed for.
Is StoreKit testing discarding in app purchase receipts when the receipt gets large but instead of discarding the oldest receipt it removes the in app purchase receipt that is not yet expired, thus forcing me to resubscribe?
Anyone else experience this issue with StoreKit testing? Seems like it's an issue with the testing environment but naturally can't be sure.
After updating my app, I'm now getting crashes when the app is brought to the foreground. On initial launch all appears to be fine. But when I background/foreground the app I get this:
Window container should not be nil.
Unfortunately this is only happening on production release and I cannot reproduce the issue in the debug environment.
I updated GoogleMobileAds to the latest version. I think the framework may be responsible. Curious to know if anyone else has experienced this and knows what could possible be the cause.
I'm unable to test Subscription renewal via StoreKit Testing in Xcode unless the subscription is a monthly subscription. I'm trying to test a weekly subscription but under the Editor menu there is no entires for anything other than Monthly? (Xcode 13.3). Setting the interval to the fastest ("Monthly Renewal Every 30 Seconds") does nothing if the active subscription is a weekly subscription. Is there no way to test subscriptions unless they are monthly?
So my app creates user notifications. Sometimes when I tap one of these notification to open the app, it crashes. It happens seemingly randomly and is not easy to reproduce. My app's UNUserNotificationCenterDelegate does something like this (shortened to keep the post concise):
-(void)userNotificationCenter:(UNUserNotificationCenter*)center
didReceiveNotificationResponse:(UNNotificationResponse*)response
withCompletionHandler:(void(^)(void))completionHandler
{
if (![response.actionIdentifier isEqualToString:UNNotificationDefaultActionIdentifier])
{
//only care about the default action...return out otherwise.
completionHandler();
return;
}
completionHandler();
UNNotificationRequest *request = response.notification.request;
NSString *requestIdentifier = request.identifier;
if (requestIdentifier == nil)
{
return;
}
[database selectModelFromId:requestIdentifier withCompletionHandler:^(MyModel *modelObj,
NSError *errorOrNil)
{
if (modelObj != nil)
{
[self makeWebViewControllerForModeAndPutOnScreen:modelObj];
}
else
{
NSLog(@"error loading data for notification...");
}
}];
}
Okay so the view controller loaded uses WKWebView to load web content. Again every once in awhile the app crashes when I tap a notification. No crash report is ever generated for my app. I don't know why this is happening. Anybody experience anything similar and know what the issue could be? Thanks in advance.
I tried adding StoreKit testing for an existing macOS app. On first launch, there is no App Store receipt on the main bundle and therefore my app calls exit(173) to get a receipt, and I get an App Store sign in sheet. Then when I sign in, I have a receipt that does not validate. I believe I'm simply getting an App Store receipt in the sandbox environment? I was under the impression that using StoreKit testing would allow me to test iAP in a local environment.
Here is my steps to reproduce:
1) Added the Configuration.storekit file to my project.
2) Set this file as the storekit configuration in the scheme editor.
3) Run the app.
4) Local receipt validation fails, macOS gives me a Mac App Store login prompt, which I can use but then I get a sandboxed App Store receipt on the main bundle. Receipt will not verify against StoreKitTestCertificate.cer.
I'm running Xcode 12.3. I'm on Big Sur. My app's deployment target is 10.11.
Any ideas? Thanks
So to support Apple Silicon in my app I need a fat version OpenSSL for Intel/Arm.
However, I cannot get OpenSSL to build for ARM if I lower the deployment target to an earlier version of macOS before Big Sur.
I was able to make a fat version of OpenSSL by making the ARM half have a deployment target of 10.15, but when added to my project, Xcode spits out warnings about Object files built for a newer macOS version than being linked.
Anyone know the proper procedure to make a backward compatible version (pre-macOS 10.15) of OpenSSL static library and still support M1 natively?
I don't think I'm currently willing to raise the deployment target of my app to 10.15 just to link the OpenSSL library.
So I'm trying to migrate some code out of the deprecated method:
(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler API_DEPRECATED("Use a BGAppRefreshTask in the BackgroundTasks framework instead", ios(7.0, 13.0), tvos(11.0, 13.0));
And into a BGAppRefreshTask. Basically what's done here is the app downloads some content and displays notification in the the Notification Center.
When I run the app on the device fire off the task via the debugger like so:
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.refreshidhere"];
The task fires. But any NSURLSessionTask instances I create fail and I get an error:
finished with error [-997] Error Domain=NSURLErrorDomain Code=-997 "Lost connection to background transfer service"
So I just made a small sample project here and still getting the error. Here is how it's configured:
(void)handleAppRefreshWithTask:(BGAppRefreshTask*)task
{
// Fetch the latest feed entries from server.
[self scheduleAppRefresh];
if (self.runningAppRefreshTask != nil)
{
NSLog(@"already running app refresh task...");
[task setTaskCompletedWithSuccess:YES];
return;
}
self.runningAppRefreshTask = task;
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.apple.com"]];
NSURLSessionDataTask *dataTask = [self.backgroundURLSessionForTest dataTaskWithRequest:request];
[task setExpirationHandler:^{
NSLog(@"Expiration handler called...");
[dataTask cancel];
}];
[dataTask resume];
}
#pragma mark - NSURLSessionDataDelegate
(void)URLSession:(NSURLSession*)session
dataTask:(nonnull NSURLSessionDataTask*)dataTask
didReceiveData:(nonnull NSData*)data
{
[self.backgroundDownloadData appendData:data];
}
(void)URLSession:(NSURLSession*)session
task:(NSURLSessionDataTask*)task
didCompleteWithError:(nullable NSError*)error
{
NSData *theData = [self.backgroundDownloadData copy];
dispatch_async(dispatch_get_main_queue(), ^{
if (error == nil)
{
NSLog(@"got %@",theData);
[self.runningAppRefreshTask setTaskCompletedWithSuccess:YES];
}
else
{
NSLog(@"error: %@",error);
[self.runningAppRefreshTask setTaskCompletedWithSuccess:NO];
}
self.runningAppRefreshTask = nil;
[self.backgroundDownloadData setData:[[NSData alloc]init]];
});
}
So yesterday, I was having a problem getting push notifications for my CloudKit app I'm working on in my development environment.
Then for some reason, this morning, I started receiving push notifications again. Now during testing, pushes have suddenly stopped. I have an iPhone and an iPad here and I'm testing on both devices.
I see there are lots of threads similar to this when I searched but was unable to find one that had a suitable answer. Here's my configuration:
1) My app only uses the private database and is using a custom zone.
2) I'm using a CKRecordZoneSubscription for silent pushes.
shouldSendContentAvailable is set to YES.
After making changes on one device, the other device gets the push. Then suddenly pushes stop working. Both apps are connected on the same wifi.
As I'm typing this, I finally just got a push for a small change on one record probably 10 minutes after it happened on the other device. The delay seems very poor.
I'd expect syncing to work a little better than this, not sure if this is just in the development environment?
So I added multiple window support for iPad in an app.
Now I understand if there are 'windows' open killing the window in the app switcher won't cause the app to terminate.
When I have two windows open in the same "scene" in split view...and I kill that scene in the app switcher, Xcode immediately terminates my debug session as if the app has been killed.
However, when I hit run to try to get a "fresh" run of the app, my split view windows are restored (I'm not using a state restoration activity)..and application:didFinishLaunchingWithOptions: is *not* called.
So even though all windows are closed (users sometimes kill apps by removing them in the app switcher manually) my app is skipping the -application:didFinishLaunchingWithOptions method in the app lifecycle.
Are users no longer able to really "quit" apps in the App Switcher when an iPad app supports multiple windows? How can a user terminate an app?
Loading a NSViewController xib from within another xib (by dragging a NSViewCOntroller object that references another xib) I'm getting incorrect results. I'm *not* using storyboards.
The view controller's view has a fixed width and is not resizable. It's set to 513.
When its unarchived from Interface Builder, the view is clipping.
So I logged out the frame in viewDidLoad, and the width of the view is unexpectedly 460.
Also I notice I have a window with a width set in IB to 513, but at runtime it's 514.
Everything in this xib is static and it has been around for years. Never used autolayout in this xib. But my only guess is autoresizing/translate masks into constraints behavior is now doing something different?
So in the CloudKit dashboard I have the "recordName" field marked as queryable.
I notice that this query fails with an error:
	 CKQuery *query = [[CKQuery alloc]initWithRecordType:recordType
predicate:[NSPredicate predicateWithFormat:@"recordName == %@",recordName]];
I get an error. It seems I have to put the recordName in a CKRecordID, and then query for recordID to essentially query by the unique recordName.
Is querying by recordName directly not supported or am I doing something wrong?